<template>
    <div class="editor-container">
        <div class="header">
            <!-- 每个图标设计的大小都不一样，每个都设置font-size以达到统一 -->
            <!-- 加粗 -->
            <span style="font-size: 16px;" class="iconfont icon-zitijiacu" @click="handleBold"></span>
            
            <!-- 高亮 -->
            <span style="font-size: 16px;" class="iconfont icon-text" @click="handleHighlight"></span>
            
            <!-- 斜体 -->
            <span style="font-size: 14px;" class="iconfont icon-zitixieti" @click="handleItalic"></span>
            
            <!-- 删除线 -->
            <span style="font-size: 14px;" class="iconfont icon-zitizhonghuaxian" @click="handleStrikethrough"></span>
            
            <!-- 标题 -->
            <el-tooltip
                effect="dark"
                placement="bottom"
                :enterable="true"
            >
                <template #content>
                    <div class="title-size">
                        <span @click="handleTitle('H1')">H1</span>
                        <span @click="handleTitle('H2')">H2</span>
                        <span @click="handleTitle('H3')">H3</span>
                        <span @click="handleTitle('H4')">H4</span>
                        <span @click="handleTitle('H5')">H5</span>
                        <span @click="handleTitle('H6')">H6</span>
                    </div>
                </template>
                <span style="font-size: 14px;" class="iconfont icon-biaotizhengwenqiehuan"></span>
            </el-tooltip>
            
            <!-- 待办事项 -->
            <span style="font-size: 16px;" class="iconfont icon-daiban" @click="handleToDoItem"></span>
            
            <!-- 超链接 -->
            <span style="font-size: 13.5px;" class="iconfont icon-lianjie" @click="handleLink"></span>
            
            <!-- 文件 -->
            <el-upload
                :action="AttachmentApi.upload"
                name="file"
                :show-file-list="false"
                :headers="fileUploadHeaders"
                :data="fileUploadExtData"
                :on-success="handleFileUploadSuccess"
            >
                <span style="font-size: 13.5px;" class="iconfont icon-23wenjian"></span>
            </el-upload>
            <span :style="{fontSize:'18px',backgroundColor:showPreview?'lightgray':'transparent'}" class="iconfont icon-fenlan" @click="showPreview=!showPreview"></span>
        </div>

        <div class="main">
            <div class="edit"
                :style="{borderRight: showPreview? '1px solid lightgray' : 'none'}"
            >
                <textarea
                    v-model="editContent"
                    ref="editRef"
                ></textarea>
            </div>

            <div class="preview beautify-scrollbar" 
                v-if="showPreview" 
                v-html="editContent"
                @click="handleImageClick"
            >
            </div>
        </div>

        <!-- 插入链接输入框 -->
        <el-dialog class="link-dialog" v-model="linkDialogVisible"  width="300" :show-close="false" :modal="false">
            <!-- @keyup.enter表示只有当回车键释放时才会触发 -->
            <el-input size="small" v-model="linkContent" placeholder="输入链接" clearable @keyup.enter="handleLink2"/>
        </el-dialog>

        <!-- 图片预览框 -->
        <el-image-viewer
            v-if="showImageViewer"
            :url-list="urlList"
            :initial-index="initialIndex"
            :infinite="false"
            @close="closeImageViewer"
        />
    </div>

</template>

<script setup>
import { $msg_e } from '@/utils/msg';
import { ref,nextTick,defineProps,defineEmits, computed } from 'vue';
import { AttachmentApi } from '@/api/path';
import { UserState } from '@/store/loginUser';


// 接收参数定义
const props = defineProps({
    // 父组件传进来的直接可以用v-html展示的内容
    content:{
        type: String,
        default: ''
    },
    // 待办事项checkbox的class前缀
    todoCheckboxClassPrefix:{
        type: String,
        default: 'todo-item-'
    }
})
// 事件定义
const emits = defineEmits(['update:content'])
const editRef = ref()
const showPreview = ref(false)
const editContent = computed({
    get: () => props.content,
    set: (val) => {
        // 父组件中用v-model:content
        emits('update:content', val);
    }
});



const handleCursor = () => {
    // 获取当前选中的文本的起始和结束位置
    let start = editRef.value.selectionStart;
    let end = editRef.value.selectionEnd;
    let text = ''
    if(start !== end){
        text = editContent.value.slice(start, end)
    }
    let obj = {start,end,text}
    // console.log('obj:',obj);
    return obj;
}


// 图片预览
const showImageViewer = ref(false)
const urlList = ref([])
const initialIndex = ref(0)
const closeImageViewer = () => {
  urlList.value = []
  initialIndex.value = 0
  showImageViewer.value = false
}
const handleImageClick = event => {
    // console.log('handleImageClick-event:',event);
    if (event.target && event.target.tagName === 'IMG') {
        urlList.value.push(event.target.src)
        showImageViewer.value = true
    }
    
}

// 链接
const linkContent = ref('')
const linkDialogVisible = ref(false)

// 上传
const fileUploadHeaders = ref({
    'x-auth-token':window.localStorage.getItem('token')
})
const fileUploadExtData = ref({
    bizType: 'editor_file',
    bizId: '' 
})
const handleFileUploadSuccess = (res, file, fileList) => {
    let data = res.data
    let previewUrl = data.previewUrl
    let downloadUrl = data.downloadUrl
    let mediaType = file.raw.type
    let fileName = file.name
    let insertText = ''
    if(mediaType.startsWith('image')) {
        insertText = `<img style='max-width:300px;' src='${previewUrl}'/>`
    }else{
        insertText = `<a href='${downloadUrl}' download='${fileName}'>${fileName}</a>`
    }
    // 插入
    let obj = handleCursor()
    let cursorPos = obj.end
    let textBefore = editContent.value.substring(0,cursorPos)
    let textAfter = editContent.value.substring(cursorPos)
    editContent.value = textBefore + insertText + textAfter
    // 更新光标位置
    cursorPos += insertText.length;
    nextTick(() => {
        editRef.value.setSelectionRange(cursorPos, cursorPos);
        editRef.value.focus();
    });

}


// 标题
const handleTitle = hsize => {
    // console.log('handleTitle-size: ' + hsize);
    let obj = handleCursor()
    if(!obj.text) return $msg_e('请选择内容')
    const hText = `<${hsize}>${obj.text}</${hsize}>`
    editContent.value = editContent.value.substring(0,obj.start) + hText + editContent.value.substring(obj.end)
}


const handleBold = () => {
    let obj = handleCursor()
    if(!obj.text) return $msg_e('请选择内容')
    const boldText = `<b>${obj.text}</b>`
    editContent.value = editContent.value.substring(0,obj.start) + boldText + editContent.value.substring(obj.end)
}

const handleItalic = () => {
    let obj = handleCursor()
    if(!obj.text) return $msg_e('请选择内容')
    const iText = `<i>${obj.text}</i>`
    editContent.value = editContent.value.substring(0,obj.start) + iText + editContent.value.substring(obj.end)
}

const handleHighlight = () => {
    let obj = handleCursor()
    if(!obj.text) return $msg_e('请选择内容')
    const hText = `<span style='background-color:yellow;'>${obj.text}</span>`
    editContent.value = editContent.value.substring(0,obj.start) + hText + editContent.value.substring(obj.end)
}

const handleStrikethrough = () => {
    let obj = handleCursor()
    if(!obj.text) return $msg_e('请选择内容')
    const strikeText = `<strike>${obj.text}</strike>`
    editContent.value = editContent.value.substring(0,obj.start) + strikeText + editContent.value.substring(obj.end)
}

const handleLink = () => {
    let obj = handleCursor()
    if(obj.text){
        const aText = `<a href='${obj.text}' target='_blank'>${obj.text}</a>`
        editContent.value = editContent.value.substring(0,obj.start) + aText + editContent.value.substring(obj.end)
    }else{
        linkDialogVisible.value = true
    }
}

const handleLink2 = () => {
    let obj = handleCursor()
    if(!linkContent.value){
        linkDialogVisible.value = false
        return
    }
    const aText = `<a href='${linkContent.value}' target='_blank'>${linkContent.value}</a>`
    let cursorPos = obj.end
    let textBefore = editContent.value.substring(0,cursorPos)
    let textAfter = editContent.value.substring(cursorPos)
    editContent.value = textBefore + aText + textAfter
    linkDialogVisible.value = false
    // 更新光标位置
    cursorPos += aText.length;
    nextTick(() => {
        editRef.value.setSelectionRange(cursorPos, cursorPos);
        editRef.value.focus();
    });
}


// 待办
const handleToDoItem = () => {
    let obj = handleCursor()
    if(!obj.text) return $msg_e('请选择内容')
    let insertText = obj.text
                        .split('\n')
                        .map(line => {
                            let loginUserId = UserState.loginUser.id
                            let id = crypto.randomUUID().replace(/-/g,'')
                            return `<label style='display:inline-flex;align-items:center;' for='${id}'><input id='${id}' type='checkbox' class='${props.todoCheckboxClassPrefix}${loginUserId}'>${line}</label>`
                        })
                        .join('\n')
    editContent.value = editContent.value.substring(0,obj.start) + insertText + editContent.value.substring(obj.end)
}



</script>

<style scoped lang="scss">
.editor-container{
    height: 100%;
    padding: 5px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    gap: 2px;
    & > .header{
        height: 30px;
        display: flex;
        flex-direction: row;
        justify-content: start;
        align-items: center;
        flex-wrap: wrap;
        gap: 5px;
        & span{
            cursor: pointer;
        }
        & span:hover{
            color: lightgreen;
        }
    }
    & > .main{
        flex: 1;
        display: flex;
        flex-direction: row;
        overflow: hidden;
        & > .edit{
            flex: 1;
            border-right: 1px solid lightgray;
            & > textarea{
                --scrollwidth:2px;
                width: 100%;
                height: 100%;
                border: 1px solid lightgray;
                box-sizing: border-box;
                border-radius: 0;
                box-shadow: none;
                padding: 5px;
                overflow-y: auto;
                color: black;
                font-size: 12px;
                outline: none;
                &::-webkit-scrollbar{
                    width: var(--scrollwidth); /* 设置滚动条的宽度 */
                }
                &::-webkit-scrollbar-thumb {
                    background-color: #DCDCDC; /* 设置滚动条滑块的颜色 */
                    border-radius: var(--scrollwidth); /* 设置滚动条滑块的圆角 */
                }
                &::-webkit-scrollbar-track {
                    background-color: #fff; /* 设置滚动条轨道的颜色 */
                    border-radius: var(--scrollwidth); /* 设置滚动条轨道的圆角 */
                }
            }
        }
        & > .preview{
            width: 50%;
            height: 100%;
            padding: 5px;
            white-space: pre-wrap; /* 保留空格和换行符 */
            font-family: monospace; /* 使用等宽字体 */
        }
    }
}


:deep(.link-dialog.el-dialog){
    padding: 10px;
}
:deep(.link-dialog .el-dialog__header){
    display: none;
}


.title-size{
    display: flex;
    flex-direction: column;
    justify-content: start;
    & > span{
        cursor: pointer;
        font-size: 10px;
    }
    & > span:hover{
        color: lightgreen;
    }
}
</style>